package com.study.example.gameserver.module.scene.bt.node;

import com.sparrow.common.ai.behaviortree.BehaviorContext;
import com.sparrow.common.ai.behaviortree.def.BTNodeStatus;
import com.sparrow.common.ai.behaviortree.node.impl.ActionNode;
import com.sparrow.common.aoi.util.MapUtil;
import com.sparrow.common.map.Position;
import com.study.example.gameserver.module.scene.entity.impl.Monster;

import java.util.List;

/**
 * 按路径移动（一次性走完路径）,返回running 控制节点持续运行
 */
public class MoveRoad extends ActionNode {
    private static final float REACH_THRESHOLD = 0.2f;

    @Override
    public BTNodeStatus tick(BehaviorContext context, long now, long delta) {
        Monster monster = context.getOwner();
        if (monster == null) {
            return BTNodeStatus.FAILURE;
        }
        List<Position> roads = monster.getRoads();
        int roadIndex = monster.getRoadIndex();
        if (roads == null || roadIndex >= roads.size()) {
            return finish(monster); // 已经没有路可走
        }
        float deltaTime = delta / 1000f;
        float step = monster.getSpeed() * deltaTime;

        Position pos = monster.getPos();
        Position target = roads.get(roadIndex);
        float dis = MapUtil.getDistance(pos, target);

        if (step >= dis) {
            // 直接到达目标点
            monster.setPos(new Position(target.getX(), pos.getY(), target.getZ()));
            monster.setRoadIndex(roadIndex + 1);
            monster.updateAngle();
            if (monster.getRoadIndex() >= roads.size()) {
                return finish(monster); // 走到最后一个点
            }
            return BTNodeStatus.RUNNING; // 继续走下一个点
        }

        // 未到目标点，移动一小步
        float dx = target.getX() - pos.getX();
        float dz = target.getZ() - pos.getZ();
        float x = pos.getX() + dx / dis * step;
        float z = pos.getZ() + dz / dis * step;
        monster.setPos(new Position(x, pos.getY(), z));

        // 是否接近目标点，切换下一个
        if (MapUtil.getDistance(monster.getPos(), target) <= REACH_THRESHOLD) {
            monster.setRoadIndex(roadIndex + 1);
            monster.updateAngle();
            if (monster.getRoadIndex() >= roads.size()) {
                return finish(monster);
            }
        }

        return BTNodeStatus.RUNNING;
    }

    private BTNodeStatus finish(Monster monster) {
        monster.setRoads(null);
        monster.setRoadIndex(0);
        return BTNodeStatus.SUCCESS;
    }

}
